
package iks.net
{
	import flash.display.*;
	import flash.errors.*;
	import flash.events.*;
	import flash.media.*;
	import flash.net.*;
	import flash.system.*;
	import iks.iface.*;
	import iks.net.*;
	
	/**
	 * 数据装载类, 能够装载不能的类型数据文件, 由自己控制加载什么类型的文件, 然后将装载的结果转化成自己需要的类型
	 */
	public final class KLoader extends EventDispatcher implements IKLoader, IKDispose
	{
		
		/**
		 * 构造函数
		 * @param	url: 所加载媒体的 URL
		 */
		public function KLoader(url : String, context : Object = null, format : String = KLoaderDataFormat.BITMAP)
		{
			m_url = url;
			
			switch (format)
			{
				case KLoaderDataFormat.BITMAP:
				case KLoaderDataFormat.SWF:
					m_loader = new Loader();
					m_loaderContext = context as LoaderContext;
					break;
					
				case KLoaderDataFormat.SOUND:
					m_sound = new Sound();
					m_soundLoaderContext = context as SoundLoaderContext;
					break;
					
				case KLoaderDataFormat.BINARY:
				case KLoaderDataFormat.TEXT:
				case KLoaderDataFormat.VARIABLES:
					m_urlLoader = new URLLoader();
					m_urlLoader.dataFormat = format;
					break;
					
				default:
					throw new ArgumentError("不支持该格式: (" + format + ")");
					break;
			}
		}
		
///////////////////////////////////////////////////////////////////////////////////////////////////
// 公共域
///////////////////////////////////////////////////////////////////////////////////////////////////
		
		/// 装载
		public function load() : void
		{
			if (KLoaderManager.getInstance().isEmpty())
				realLoad();
			
			KLoaderManager.getInstance().offer(this);
		}
		
		/// 获得加载的url
		public function get url() : String
		{
			return m_url;
		}
		
		/// 获得加载的内容, 这个根据装载类型决定内容是什么类型
		public function get content() : *
		{
			return m_content;
		}
		
///////////////////////////////////////////////////////////////////////////////////////////////////
// 接口实现
///////////////////////////////////////////////////////////////////////////////////////////////////
		
		/// 在下载操作过程中收到数据
		public function get percent() : Number
		{
			return m_percent;
		}
		
		/// 成功加载数据后调度
		public function get isComplete() : Boolean
		{
			return m_isComplete;
		}
		
		/// 释放资源
		public function dispose() : void
		{
			if (m_isDisposed)
				return;
			m_isDisposed = true;
			
			// 如果装载没有完成, 则从管理队列中弹出队列头重新装载
			if (!isComplete)
			{
				KLoaderManager.getInstance().poll();
				var head : KLoader = KLoaderManager.getInstance().getLoader(0);
				if (head != null)
					head.realLoad();
			}
			
			unload();
			m_content = null;
		}
		
///////////////////////////////////////////////////////////////////////////////////////////////////
// 私有域
///////////////////////////////////////////////////////////////////////////////////////////////////
		
		/// 添加侦听事件, 并且装载资源
		private function realLoad() : void
		{
			if (m_loader != null)
			{
				m_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadCompleteHandler);
				m_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
				m_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadProgressHandler);
				m_loader.load(new URLRequest(m_url), m_loaderContext);
			}
			
			if (m_sound != null)
			{
				m_sound.addEventListener(Event.COMPLETE, onLoadCompleteHandler);
				m_sound.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
				m_sound.addEventListener(ProgressEvent.PROGRESS, onLoadProgressHandler);
				m_sound.load(new URLRequest(m_url), m_soundLoaderContext);
			}
			
			if (m_urlLoader != null)
			{
				m_urlLoader.addEventListener(Event.COMPLETE, onLoadCompleteHandler);
				m_urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
				m_urlLoader.addEventListener(ProgressEvent.PROGRESS, onLoadProgressHandler);
				m_urlLoader.load(new URLRequest(m_url));
			}
		}
		
		/// 卸载所有资源
		private function unload() : void
		{
			if (m_loader != null)
			{
				try
				{
					m_loader.close();
				}
				catch (e : Error)
				{
					
				}
				finally
				{
					// 卸载事件
					m_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadCompleteHandler);
					m_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
					m_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onLoadProgressHandler);
					
					m_loader.unloadAndStop(true);
					m_loader = null;
					m_loaderContext = null;
				}
			}
			
			if (m_sound != null)
			{
				try
				{
					m_sound.close();
				}
				catch (e : Error)
				{
				}
				finally
				{
					m_sound.removeEventListener(Event.COMPLETE, onLoadCompleteHandler);
					m_sound.removeEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
					m_sound.removeEventListener(ProgressEvent.PROGRESS, onLoadProgressHandler);
					m_sound = null;
					m_soundLoaderContext = null;
				}
			}
			
			if (m_urlLoader != null)
			{
				try
				{
					m_urlLoader.close();
				}
				catch (e : Error)
				{
				}
				finally
				{
					m_urlLoader.removeEventListener(Event.COMPLETE, onLoadCompleteHandler);
					m_urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
					m_urlLoader.removeEventListener(ProgressEvent.PROGRESS, onLoadProgressHandler);
					m_urlLoader = null;
				}
			}
		}
		
		/// 装载完成事件
		private function onLoadCompleteHandler(evt : Event) : void
		{
			if (evt.target is LoaderInfo)
			{
				// 获得加载的 SWF 文件或图像（JPG、PNG 或 GIF）文件的根显示对象
				m_content = evt.target.content;
				
			}
			else if (evt.target is Sound)
			{
				// 获得声音显示对象
				m_content = m_sound;
			}
			else if (evt.target is URLLoader)
			{
				// 获得加载的数据
				m_content = evt.target.data;
			}
			
			m_isComplete = true;
			this.dispatchEvent(new Event(Event.COMPLETE));
			
			// 装载完KLoader将其从队列中弹出
			KLoaderManager.getInstance().poll();
			
			// 从KLoader队列头取出一个KLoader对象, 继续装载
			var head : KLoader = KLoaderManager.getInstance().getLoader(0);
			if (head != null)
				head.realLoad();
		}
		
		/// 装载错误, 将重新装载
		private function onIOErrorHandler(evt : IOErrorEvent) : void
		{
			// 当前队首的装载的KLoader装载错误, 那么将此弹出装载队列
			// 并且让后面的Kloader继续装载
			KLoaderManager.getInstance().poll();
			var head : KLoader = KLoaderManager.getInstance().getLoader(0);
			if (head != null)
				head.realLoad();
			
			if (this.hasEventListener(IOErrorEvent.IO_ERROR))
				this.dispatchEvent(evt);
			else
				throw new IOError(evt.text);
		}
		
		/// 装载进度
		private function onLoadProgressHandler(evt : ProgressEvent) : void
		{
			m_percent = Number(evt.bytesLoaded) / Number(evt.bytesTotal);
			this.dispatchEvent(evt);
		}
		
		private var m_url : String = "";
		private var m_content : * = null;
		private var m_percent : Number = 0;
		private var m_isComplete : Boolean = false;
		private var m_isDisposed : Boolean = false;
		
		// swf, jpg, png, gif
		private var m_loader : Loader = null;
		private var m_loaderContext : LoaderContext = null;
		
		// sound
		private var m_sound : Sound = null;
		private var m_soundLoaderContext : SoundLoaderContext = null;
		
		// binary, text, variables
		private var m_urlLoader : URLLoader = null;
	}
}


































///////////////////////////////////////////////////////////////////////////////////////////////////
// end file


